<?php
/**
 * Created by PhpStorm.
 * User: cc
 * Date: 2024/8/8
 * Time: 16:22
 */

namespace app\api\controller\v49;

use app\api\controller\v2\Auth;
use app\chat\LiveMessage;
use app\common\cachemodel\zl8\Zl8AstrChatBusyDateRecord;
use app\common\cachemodel\zl8\Zl8AstrChatBusyRecord;
use app\common\cachemodel\zl8\Zl8UserChatReservationRecord;
use app\common\cachemodel\ZlcrAstr;
use app\zyhsapi\model\ZyhsConsultChatRecord;
use app\zyhsapi\model\ZyhsConsultChatRecordAstr;
use app\zyhsapi\model\ZyhsConsultChatRecordDetails;
use think\Db;
use think\response\Json;

class UserConsultChat extends Auth
{
    private $appType2 = 2;

    /**
     * 预约列表
     * @return Json
     * @throws \Exception
     */
    public function userReservationList()
    {
        $astrId = input('astr_id/d', 0);
        if (!$astrId)
        {
            return show(config('code.error'), '请求异常');
        }
        $zl8UserChatReservationRecordModel = new Zl8UserChatReservationRecord();
        $reservationTimeListConfig = $zl8UserChatReservationRecordModel->reservationTimeList;
        $dateList = $this->generateDateList(2);
        $data = [];
        // 获取指定咨询师的预约记录
        $astrReservationList = $zl8UserChatReservationRecordModel->getAstrReservationList($astrId);
        // 获取当前用户的预约记录
        $userReservationList = $zl8UserChatReservationRecordModel->getUserReservationList($this->user['id']);


        //获取咨询师休息记录
        $astrRestList = (new Zl8AstrChatBusyRecord())->getAstrChatBusyList($astrId);
        $astrRestListMap = array_flip($astrRestList); // 创建映射以提高查找速度
        $astrDateRestList = (new Zl8AstrChatBusyDateRecord())->getAstrDateBusyList($astrId);

        $now = time();
        foreach ($dateList as $key => $item)
        {
            $appointmentInfo = null;
            $reservationTimeList = [];
            foreach ($reservationTimeListConfig as $id => $value)
            {
                //用户可预约今天（未来2小时以上）、明天、后天的时间
                $hIdTmp = $id === 24 ? 23 : $id - 1;
                $time = strtotime($item['date'] . " {$hIdTmp}:00");//预约时间
                $nowTime = $now + 3600; // 当前时间之后2小时
                $dateTheDayAfterTomorrow = strtotime(date('Y-m-d')) + 72 * 3600 - 1; // 两天后的时间
                if ($nowTime > $time || $time > $dateTheDayAfterTomorrow)
                {
                    $is_valid = 0;
                }//处理当前时间段咨询师是否休息
                else
                {
                    $is_valid = in_array($item['date2'], $astrDateRestList, false) ? 0 : 1;
                    $is_valid = isset($astrRestListMap[$id]) ? 0 : $is_valid;
                }
                //处理用户当前时间段预约信息
                $reservationInfo = $this->processReservationInfo($userReservationList, 'user', $key . $id, $zl8UserChatReservationRecordModel);
                if ($reservationInfo)
                {
                    $appointmentInfo = $reservationInfo;
                    $is_valid = 0;
                } else
                {
                    //处理咨询师当前时间段预约信息
                    $reservationInfo = $this->processReservationInfo($astrReservationList, 'astr', $key . $id, $zl8UserChatReservationRecordModel);
                    if ($reservationInfo)
                    {
                        $is_valid = 0;
                    }
                }
                $reservationTimeList[] = [
                    'id' => $id,
                    'is_valid' => $is_valid,
                    'content' => $value
                ];
            }
            $data[] = [
                'tab_name' => $item['name'],
                'date' => $item['date'],
                'time_list' => $reservationTimeList,
                'appointment_info' => $appointmentInfo ?? null
            ];
        }
        return show(config('code.success'), '', $data);
    }

    /**
     * 生成日期列表
     * @param $daysAhead
     * @return array
     */
    private function generateDateList($daysAhead)
    {
        $dateList = [];
        for ($i = 0; $i <= $daysAhead; $i++)
        {
            $date = date('Ymd', strtotime("+$i days"));
            $dateList[$date] = [
                'date' => date('Y-m-d', strtotime("+$i days")),
                'date2' => $date,
                'name' => $i === 0 ? '今天' : ($i === 1 ? '明天' : '后天')
            ];
        }
        return $dateList;
    }


    /**
     * 处理预约信息的函数
     * @param $list
     * @param $type
     * @param $needItem
     * @param $model
     * @return array|null
     * @throws \Exception
     */
    private function processReservationInfo($list, $type, $needItem, $model)
    {
        $ids = array_keys($list);
        $reservationInfo = $model->batchGetInfoByIds($ids);
        foreach ($reservationInfo as $info)
        {
            $dateTmp = $info['date'] . $info['h_id'];
            if ($needItem === $dateTmp && in_array($info['status'], [
                    $model->statusList['waiting_response'],
                    $model->statusList['wait_keep_promise'],
                ], true))
            {
                if ($type === 'user')
                {
                    $astrInfo = (new ZlcrAstr())->getInfoById($info['astr_id']);
                    return [
                        'id' => $info['id'],
                        'avatar' => $astrInfo['avatar'],
                        'name' => $astrInfo['nickname'],
                        'time_desc' => date('n月j日', strtotime($info['date'])) . ' ' . $model->reservationTimeList[$info['h_id']]
                    ];
                }
                return null;
            }
        }
        return null;
    }

    /**
     * 用户预约
     * @return Json
     * @throws \Exception
     */
    public function userReservation()
    {
        $astrId = input('astr_id/d', '');
        $date = input('date/s', '');
        $hId = input('h_id/d', '');
        $now = time();
        function isValidDate($date, $format = 'Y-m-d')
        {
            $timestamp = strtotime($date);
            if ($timestamp === false)
            {
                return false;
            }
            return date($format, $timestamp) == $date;
        }

        if (isValidDate($date) === false)
        {
            return show(config('code.error'), '日期格式不正确');
        }
        $dateTime = strtotime($date);
        $zl8UserChatReservationRecordModel = new Zl8UserChatReservationRecord();
        $reservationTimeListConfig = $zl8UserChatReservationRecordModel->reservationTimeList;
        if (!isset($reservationTimeListConfig[$hId]))
        {
            return show(config('code.error'), '请求异常');
        }

        //用户可预约今天（未来2小时以上）、明天、后天的时间
        $hIdTmp = $hId === 24 ? 23 : $hId - 1;
        $time = strtotime($date . " {$hIdTmp}:00");//预约时间
        $nowTime = $now + 3600; // 当前时间之后2小时
        $dateTheDayAfterTomorrow = strtotime(date('Y-m-d')) + 72 * 3600 - 1; // 两天后的时间
        if ($nowTime > $time || $time > $dateTheDayAfterTomorrow)
        {
            return show(config('code.error'), '预约时间超出范围');
        }

        $astrInfo = (new ZlcrAstr())->getInfoById($astrId);
        if (!$astrInfo)
        {
            return show(config('code.error'), '咨询师不存在');
        }
        //每天只可以预约一次
        $userReservationList = $zl8UserChatReservationRecordModel->getUserReservationList($this->user['id']);
        if ($userReservationList)
        {
            $ids = array_keys($userReservationList);
            $dateTmp = (int)date('Ymd', $dateTime);
            $userReservationInfo = $zl8UserChatReservationRecordModel->batchGetInfoByIds($ids);
            foreach ($userReservationInfo as $item)
            {
                if ($item['date'] === $dateTmp && in_array($item['status'], [
                        $zl8UserChatReservationRecordModel->statusList['waiting_response'],
                        $zl8UserChatReservationRecordModel->statusList['wait_keep_promise'],
                    ], true))
                {
                    return show(config('code.error'), '当天已经预约其他咨询师');
                }
            }
        }
        //插入会话
        $consultChatIdModel = new ZyhsConsultChatRecord();
        $chatId = $consultChatIdModel->getChatIdByAstrId($this->appType2, $this->user['id'], $astrId);
        if (!$chatId)
        {
            $insertData = [
                'app_type' => $this->appType2,
                'uid' => $this->user['id'],
                'astr_id' => $astrId,
                'last_chat_detail_id' => 0,
                'last_chat_detail_time' => 0,
                'create_time' => $this->request->time(),
            ];
            // 创建新的会话
            $chatId = $consultChatIdModel->SaveData($insertData);
        }
        if ($chatId)
        {
            $timeDes = date('Y年n月j日', $dateTime) . ' ' . $reservationTimeListConfig[$hId];
            $consultMsgData = [
                'chat_id' => $chatId,
                'app_type' => $this->appType2,
                'uid' => $this->user['id'],
                'astr_id' => $astrId,
                'type' => 2,    //  1=>APP消息 2=>用户发送消息
                'title' => '',
                'content' => $timeDes, // 提问问题
                'data_type' => 9,   // 9=>预约消息
                'pid' => 0, // 待更新
                'extend' => json_encode([
                    'reservation_info' => [
                        'title' => '预约',
                        'content' => '',
                        'time_des' => $timeDes,
                        'status' => $zl8UserChatReservationRecordModel->statusList['waiting_response'],
                    ]
                ], JSON_UNESCAPED_UNICODE),
                'create_time' => $this->request->time(),
            ];
            $consultChatRecordDetailsModel = new ZyhsConsultChatRecordDetails();
            $resData = $consultChatRecordDetailsModel->SaveData($chatId, $consultMsgData);
            if ($resData)
            {
                // 更新用户端 最后咨询信息
                $consultChatIdModel->updateData($chatId, [
                    'uid' => $this->user['id'],
                    'last_chat_detail_id' => $resData['id'],
                    'last_chat_detail_time' => $this->request->time(),
                ], $this->appType2);
                //更新咨询师端 最后咨询信息并给咨询师添加可回复消息次数
                $zlcr3ConsultChatRecordAstrModel = new ZyhsConsultChatRecordAstr();
                $zlcr3ConsultChatRecordAstrModel->userSendUpdate($this->appType2, $this->user['id'], $astrId, [
                    'last_chat_detail_id' => $resData['id'],
                    'last_chat_detail_time' => $this->request->time(),
                    'user_last_msg_time' => $this->request->time(),
                    'unread_num' => Db::raw('unread_num + 1'),
                    'question_num' => Db::raw('question_num + 1'),
                ]);

                //  增加咨询师 可回复次数
                $astrChatId = $zlcr3ConsultChatRecordAstrModel->getIdByAstrIdAndUid($astrId, $this->appType2, $this->user['id']);
                $astrChatIdInfo = $zlcr3ConsultChatRecordAstrModel->getInfoById($astrChatId);
                if ($astrChatIdInfo['call_delay_num'] < 3)
                {
                    $astrChatIdInfo['call_delay_num'] = 3;
                    $zlcr3ConsultChatRecordAstrModel->UpdateData($astrChatId, $astrId, [
                        'call_delay_num' => 3,
                    ]);
                }

                $res = $zl8UserChatReservationRecordModel->saveData([
                    'status' => $zl8UserChatReservationRecordModel->statusList['waiting_response'],
                    'char_id' => $resData['id'],
                    'uid' => $this->user['id'],
                    'astr_id' => $astrId,
                    'date' => date('Ymd', $dateTime),
                    'h_id' => $hId,
                    'create_time' => $this->request->time()
                ]);

                if ($res)
                {
                    // 判断咨询师是否在线
                    if (LiveMessage::getUserIsOnline(2, $astrId))
                    {
                        $astrChatInfo = $zlcr3ConsultChatRecordAstrModel->getUserAstrChatInfo($this->appType2, $this->user['id'], $astrId);
                        // 向 咨询师发送消息
                        $astrData2 = current($consultChatRecordDetailsModel->astrDataListResert([$resData], [], $this->user, $this->appType2));
                        LiveMessage::sendMsg(LiveMessage::who(LiveMessage::WHO_TYPE_ASTRO, 0, $astrId), LiveMessage::MSG_TYPE_POP_CONSULT_MSG, [
                            'msg_type' => 2,
                            'app_type' => $this->appType2,
                            'uid' => $this->user['id'],
                            'num' => $astrChatInfo['delay_num'] + 3,
                            'msg_data' => $astrData2,
                        ]);
                    }

                    return show(config('code.success'), 'success.', [
                        'id' => $res,
                        'avatar' => $astrInfo['avatar'],
                        'name' => $astrInfo['nickname'],
                        'time_desc' => $timeDes
                    ]);
                }
            }
        }
        return show(config('code.error'), '服务异常，请稍后重试～');
    }

    /**
     * 取消预约
     * @return Json
     * @throws \Exception
     */
    public function cancelReservation()
    {
        $id = input('id/d', 0);
        $zl8UserChatReservationRecordModel = new Zl8UserChatReservationRecord();
        $reservationInfo = $zl8UserChatReservationRecordModel->getInfoById($id);
        if (!$reservationInfo || $reservationInfo['uid'] != $this->user['id'] || !in_array($reservationInfo['status'], [
                $zl8UserChatReservationRecordModel->statusList['waiting_response'],
                $zl8UserChatReservationRecordModel->statusList['wait_keep_promise'],
            ], true))
        {
            return show(config('code.error'), '服务异常，请稍后重试～');
        }
        $res = $zl8UserChatReservationRecordModel->updateData($id, ['status' => $zl8UserChatReservationRecordModel->statusList['user_cancel'], 'update_time' => $this->request->time()]);
        if ($res)
        {
            $consultChatRecordDetailsModel = new ZyhsConsultChatRecordDetails();
            $chatDetail = $consultChatRecordDetailsModel->getInfoById($reservationInfo['char_id']);
            $chatDetail['extend']['reservation_info']['status'] = $zl8UserChatReservationRecordModel->statusList['user_cancel'];
            $chatDetail['extend']['reservation_info']['title'] = '预约已取消';
            $chatDetail['extend']['reservation_info']['content'] = '我已取消预约，下次再聊';
            $consultChatRecordDetailsModel->UpdateData($chatDetail['id'], ['extend' => $chatDetail['extend']]);

            // 判断咨询师是否在线
            if (LiveMessage::getUserIsOnline(2, $reservationInfo['astr_id']))
            {
                $zlcr3ConsultChatRecordAstrModel = new ZyhsConsultChatRecordAstr();
                $astrChatInfo = $zlcr3ConsultChatRecordAstrModel->getUserAstrChatInfo($this->appType2, $this->user['id'], $reservationInfo['astr_id']);
                // 向 咨询师发送消息
                $astrData2 = current($consultChatRecordDetailsModel->astrDataListResert([$chatDetail], [], $this->user, $this->appType2));
                LiveMessage::sendMsg(LiveMessage::who(LiveMessage::WHO_TYPE_ASTRO, 0, $reservationInfo['astr_id']), LiveMessage::MSG_TYPE_POP_CONSULT_MSG, [
                    'msg_type' => 2,
                    'app_type' => $this->appType2,
                    'uid' => $this->user['id'],
                    'num' => $astrChatInfo['delay_num'],
                    'msg_data' => $astrData2,
                ]);
            }

            return show(config('code.success'), '取消完成～');
        }
        return show(config('code.error'), '服务异常，请稍后重试～');
    }
}
